#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
参数存储管理模块（类似 Vue Store）

提供全局参数管理、持久化存储和状态同步功能
"""

import json
import os
import multiprocessing
from settings import BASE_DIR


class ParamsStore:
    """
    参数存储管理类
    
    功能：
    - 全局参数管理
    - 自动持久化到 JSON 文件
    - 单例模式，确保全局唯一
    """
    
    _instance = None
    _initialized = False
    
    def __new__(cls):
        """单例模式：确保只有一个实例"""
        if cls._instance is None:
            cls._instance = super(ParamsStore, cls).__new__(cls)
        return cls._instance
    
    def __init__(self):
        """初始化参数存储"""
        if ParamsStore._initialized:
            return
        
        ParamsStore._initialized = True
        
        # 参数文件路径
        self.params_file = os.path.join(BASE_DIR, 'config', 'params.json')
        
        # 确保配置目录存在
        os.makedirs(os.path.dirname(self.params_file), exist_ok=True)
        
        # 默认参数
        self._default_params = {
            'simion_path': r"D:\SIMION-2024\simion.exe",
            'iob_path': '',
            'lua_path': '',
            'csv_save_path': '',
            '_rfvolt': None,
            '_rfvolt2': None,
            '_frequency_start': None,
            '_frequency_end': None,
            '_frequency_step': 10000,
            '_frequency_list': [],  # 生成的频率列表
            '_ke': 90000.0,
            '_length': 500.0,
            'thread_count': multiprocessing.cpu_count(),  # 自动检测CPU核心数
            'keep_workspace': False,  # 是否保留工作空间用于调试
            # 界面外观设置
            'appearance_theme': 'cosmo',  # 主题：cosmo, journal, darkly, flatly, litera, lumen, minty, pulse, sandstone, united, yeti
            'appearance_font_size': 9,  # 字体大小
            'appearance_window_width': 1200,  # 窗口宽度
            'appearance_window_height': 800,  # 窗口高度
            'appearance_window_resizable': True,  # 是否允许调整窗口大小
            'appearance_window_remember_size': True  # 是否记住窗口大小
        }
        
        # 当前参数（从文件加载或使用默认值）
        self._params = self._load_params()
        
        # 观察者列表（用于参数变化通知）
        self._observers = []
    
    def _load_params(self):
        """从文件加载参数"""
        try:
            if os.path.exists(self.params_file):
                with open(self.params_file, 'r', encoding='utf-8') as f:
                    loaded_params = json.load(f)
                    # 合并默认参数和加载的参数（确保新增参数有默认值）
                    params = self._default_params.copy()
                    params.update(loaded_params)
                    return params
        except Exception as e:
            print(f"加载参数失败: {e}")
        
        # 如果加载失败，返回默认参数
        return self._default_params.copy()
    
    def _save_params(self):
        """保存参数到文件"""
        try:
            with open(self.params_file, 'w', encoding='utf-8') as f:
                json.dump(self._params, f, indent=4, ensure_ascii=False)
            return True
        except Exception as e:
            print(f"保存参数失败: {e}")
            return False
    
    def get(self, key, default=None):
        """
        获取参数值
        
        参数:
            key: 参数键名
            default: 默认值（如果参数不存在）
        
        返回:
            参数值
        """
        return self._params.get(key, default)
    
    def get_all(self):
        """获取所有参数"""
        return self._params.copy()
    
    def set(self, key, value):
        """
        设置单个参数
        
        参数:
            key: 参数键名
            value: 参数值
        """
        old_value = self._params.get(key)
        self._params[key] = value
        
        # 通知观察者
        if old_value != value:
            self._notify_observers(key, value, old_value)
    
    def update(self, params_dict):
        """
        批量更新参数
        
        参数:
            params_dict: 参数字典
        """
        for key, value in params_dict.items():
            self.set(key, value)
    
    def save(self):
        """
        保存当前参数到文件（持久化）
        
        返回:
            bool: 保存成功返回 True
        """
        return self._save_params()
    
    def reset(self):
        """重置为默认参数"""
        self._params = self._default_params.copy()
        self._save_params()
        # 通知所有观察者
        for key in self._params:
            self._notify_observers(key, self._params[key], None)
    
    def reset_key(self, key):
        """重置单个参数为默认值"""
        if key in self._default_params:
            self.set(key, self._default_params[key])
            self._save_params()
    
    def subscribe(self, observer):
        """
        订阅参数变化
        
        参数:
            observer: 观察者函数，签名为 observer(key, new_value, old_value)
        """
        if observer not in self._observers:
            self._observers.append(observer)
    
    def unsubscribe(self, observer):
        """取消订阅"""
        if observer in self._observers:
            self._observers.remove(observer)
    
    def _notify_observers(self, key, new_value, old_value):
        """通知所有观察者"""
        for observer in self._observers:
            try:
                observer(key, new_value, old_value)
            except Exception as e:
                print(f"通知观察者失败: {e}")
    
    def generate_frequency_list(self):
        """
        根据起始频率、结束频率和步长生成频率列表
        
        Returns:
            list: 生成的频率列表
        """
        try:
            freq_start = self.get('_frequency_start')
            freq_end = self.get('_frequency_end')
            freq_step = self.get('_frequency_step', 10000)
            
            # 如果起始或结束频率为空，返回空列表
            if freq_start is None or freq_end is None:
                frequency_list = []
            else:
                # 转换为浮点数
                start = float(freq_start)
                end = float(freq_end)
                step = float(freq_step)
                
                # 如果起始和结束频率相同，返回只有一个元素的列表
                if start == end:
                    frequency_list = [start]
                else:
                    # 生成频率列表
                    frequency_list = []
                    current = start
                    
                    if start < end:
                        # 递增
                        while current <= end:
                            frequency_list.append(current)
                            current += step
                    else:
                        # 递减
                        while current >= end:
                            frequency_list.append(current)
                            current -= step
            
            # 保存频率列表到参数中
            self.set('_frequency_list', frequency_list)
            
            return frequency_list
            
        except Exception as e:
            print(f"生成频率列表失败: {e}")
            return []
    
    def __repr__(self):
        """字符串表示"""
        return f"ParamsStore({self._params})"


# 全局单例实例
params_store = ParamsStore()


# 便捷函数
def get_param(key, default=None):
    """获取参数（便捷函数）"""
    return params_store.get(key, default)


def set_param(key, value):
    """设置参数（便捷函数）"""
    params_store.set(key, value)


def get_all_params():
    """获取所有参数（便捷函数）"""
    return params_store.get_all()


def update_params(params_dict):
    """更新参数（便捷函数）"""
    params_store.update(params_dict)


def save_params():
    """保存参数（便捷函数）"""
    return params_store.save()


def reset_params():
    """重置参数（便捷函数）"""
    params_store.reset()


def generate_frequency_list():
    """生成频率列表（便捷函数）"""
    return params_store.generate_frequency_list()


# 使用示例
if __name__ == '__main__':
    # 获取参数
    print("SIMION 路径:", get_param('simion_path'))
    print("RF 电压 1:", get_param('_rfvolt'))
    
    # 设置参数
    set_param('_rfvolt', 6000.0)
    print("更新后 RF 电压 1:", get_param('_rfvolt'))
    
    # 保存参数
    save_params()
    print("参数已保存")
    
    # 获取所有参数
    print("\n所有参数:")
    for key, value in get_all_params().items():
        print(f"  {key}: {value}")

